-
-
Notifications
You must be signed in to change notification settings - Fork 574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: use #
for private methods to reduce the minified file size
#3596
Conversation
#
for private methods to reduce the bundle size#
for private methods to reduce the minified bundle size
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #3596 +/- ##
==========================================
- Coverage 94.71% 89.74% -4.97%
==========================================
Files 158 158
Lines 9552 10086 +534
Branches 2825 2809 -16
==========================================
+ Hits 9047 9052 +5
- Misses 505 1034 +529 ☔ View full report in Codecov by Sentry. |
#
for private methods to reduce the minified bundle size#
for private methods to reduce the minified file size
What do you think of this? |
I think it's a nice idea. |
I'm not sure how much this change will affect real world examples, but parsing time may be reduced, and the file upload time to the production environment will be faster, although super slightly. |
Good idea! Updated 24d4fb1 |
Hi @yusukebe, I think it's a really good refactoring 👍 How to define instance methodsThis is another refactoring story, but instance methods are faster to create instances if they are written directly than if they are defined by assignment. Given this background, we would like to carefully consider the following line of approach. import { run, bench, group } from 'mitata'
bench('noop', () => {})
class A {
method = () => {}
#method2 = this.method
}
class B {
method() {
// noop
}
#method2() {
this.method()
}
}
group('create instance', () => {
bench('class A', () => new A())
bench('class B', () => new B())
})
await run()
|
@yusukebe Thank you! benchmark - 2Here is a version of the benchmark with a few additions.
The results are almost the same for import { run, bench, group } from 'mitata'
bench('noop', () => {})
class A {
method = () => {}
}
class B {
method() {
// noop
}
}
const method = () => {}
class C {
method = method
}
group('create instance', () => {
bench('class A', () => new A().method())
bench('class B', () => new B().method())
bench('class C', () => new C().method())
})
run()
c.newRespons vs. c.#newRespons
For the reasons given above, why not give diff --git a/src/context.ts b/src/context.ts
index a591db72..363b6556 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -624,11 +624,11 @@ export class Context<
return Object.fromEntries(this.#var)
}
- newResponse: NewResponse = (
+ #newResponse(
data: Data | null,
arg?: StatusCode | ResponseInit,
headers?: HeaderRecord
- ): Response => {
+ ): Response {
// Optimized
if (this.#isFresh && !headers && !arg && this.#status === 200) {
return new Response(data, {
@@ -690,10 +690,7 @@ export class Context<
})
}
- #newResponse(...args: unknown[]) {
- // @ts-expect-error Type mismatch for args in newResponse call
- return this.newResponse(...args)
- }
+ newResponse: NewResponse = (...args) => this.#newResponse(...(args as Parameters<NewResponse>))
/**
* `.body()` can return the HTTP response. |
@yusukebe Thank you! Do you think this change is something you don't want to add? (Because it's a change that's in my comments but not in 3ac8d62) Well, it may not be necessary, but from the benchmark, performance decreases with each additional diff --git a/src/context.ts b/src/context.ts
index 3bb9ceda..86124e00 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -623,11 +623,11 @@ export class Context<
return Object.fromEntries(this.#var)
}
- #newResponse: NewResponse = (
+ #newResponse(
data: Data | null,
arg?: StatusCode | ResponseInit,
headers?: HeaderRecord
- ): Response => {
+ ): Response {
// Optimized
if (this.#isFresh && !headers && !arg && this.#status === 200) {
return new Response(data, { |
@usualoma Thanks! Or like this? diff --git a/src/context.ts b/src/context.ts
index 3bb9ceda..6a2f8f47 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -623,11 +623,11 @@ export class Context<
return Object.fromEntries(this.#var)
}
- #newResponse: NewResponse = (
+ #newResponse(
data: Data | null,
arg?: StatusCode | ResponseInit,
headers?: HeaderRecord
- ): Response => {
+ ): Response {
// Optimized
if (this.#isFresh && !headers && !arg && this.#status === 200) {
return new Response(data, {
@@ -689,7 +689,9 @@ export class Context<
})
}
- newResponse: NewResponse = (...args) => this.#newResponse(...(args as Parameters<NewResponse>))
+ newResponse(...args: Parameters<NewResponse>) {
+ return this.#newResponse(...args)
+ }
/**
* `.body()` can return the HTTP response. |
@yusukebe Thank you for your consideration. I think that would mean that the intended type would no longer be available for the public API |
Thanks! Probably, the type definition is not good. How about changing diff --git a/src/context.ts b/src/context.ts
index 3bb9ceda..3bf30cef 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -107,8 +107,7 @@ interface Set<E extends Env> {
* Interface for creating a new response.
*/
interface NewResponse {
- (data: Data | null, status?: StatusCode, headers?: HeaderRecord): Response
- (data: Data | null, init?: ResponseInit): Response
+ (data: Data | null, arg?: StatusCode | ResponseInit, headers?: HeaderRecord): Response
}
/**
@@ -623,11 +622,11 @@ export class Context<
return Object.fromEntries(this.#var)
}
- #newResponse: NewResponse = (
+ #newResponse(
data: Data | null,
arg?: StatusCode | ResponseInit,
headers?: HeaderRecord
- ): Response => {
+ ): Response {
// Optimized
if (this.#isFresh && !headers && !arg && this.#status === 200) {
return new Response(data, {
@@ -689,7 +688,9 @@ export class Context<
})
}
- newResponse: NewResponse = (...args) => this.#newResponse(...(args as Parameters<NewResponse>))
+ newResponse(...args: Parameters<NewResponse>) {
+ return this.#newResponse(...args)
+ }
/**
* `.body()` can return the HTTP response. |
@yusukebe Thank you! I don't think that's what we wanted to do with the original definition, because it would accept the following. If we prioritize performance over being DRY, I think the only way to write it is as follows diff --git a/src/context.ts b/src/context.ts
index 3bb9ceda..cd60ef1f 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -623,11 +623,11 @@ export class Context<
return Object.fromEntries(this.#var)
}
- #newResponse: NewResponse = (
+ #newResponse(
data: Data | null,
arg?: StatusCode | ResponseInit,
headers?: HeaderRecord
- ): Response => {
+ ): Response {
// Optimized
if (this.#isFresh && !headers && !arg && this.#status === 200) {
return new Response(data, {
@@ -689,7 +689,13 @@ export class Context<
})
}
- newResponse: NewResponse = (...args) => this.#newResponse(...(args as Parameters<NewResponse>))
+ newResponse(data: Data | null, status?: StatusCode, headers?: HeaderRecord): Response
+ newResponse(data: Data | null, init?: ResponseInit): Response
+ newResponse(
+ ...args: [data: Data | null, arg?: StatusCode | ResponseInit, headers?: HeaderRecord]
+ ): Response {
+ return this.#newResponse(...args)
+ }
/**
* `.body()` can return the HTTP response. Or, we could go one step further and do this. diff --git a/src/context.ts b/src/context.ts
index 3bb9ceda..72069c1e 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -103,19 +103,6 @@ interface Set<E extends Env> {
<Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void
}
-/**
- * Interface for creating a new response.
- */
-interface NewResponse {
- (data: Data | null, status?: StatusCode, headers?: HeaderRecord): Response
- (data: Data | null, init?: ResponseInit): Response
-}
-
-/**
- * Interface for responding with a body.
- */
-interface BodyRespond extends NewResponse {}
-
/**
* Interface for responding with text.
*
@@ -623,11 +610,11 @@ export class Context<
return Object.fromEntries(this.#var)
}
- #newResponse: NewResponse = (
+ #newResponse(
data: Data | null,
arg?: StatusCode | ResponseInit,
headers?: HeaderRecord
- ): Response => {
+ ): Response {
// Optimized
if (this.#isFresh && !headers && !arg && this.#status === 200) {
return new Response(data, {
@@ -689,7 +676,13 @@ export class Context<
})
}
- newResponse: NewResponse = (...args) => this.#newResponse(...(args as Parameters<NewResponse>))
+ newResponse(data: Data | null, status?: StatusCode, headers?: HeaderRecord): Response
+ newResponse(data: Data | null, init?: ResponseInit): Response
+ newResponse(
+ ...args: [data: Data | null, arg?: StatusCode | ResponseInit, headers?: HeaderRecord]
+ ): Response {
+ return this.#newResponse(...args)
+ }
/**
* `.body()` can return the HTTP response.
@@ -712,11 +705,9 @@ export class Context<
* })
* ```
*/
- body: BodyRespond = (
- data: Data | null,
- arg?: StatusCode | ResponseInit,
- headers?: HeaderRecord
- ): Response => {
+ body(data: Data | null, init?: ResponseInit): Response
+ body(data: Data | null, status?: StatusCode, headers?: HeaderRecord): Response
+ body(data: Data | null, arg?: StatusCode | ResponseInit, headers?: HeaderRecord): Response {
return typeof arg === 'number'
? this.#newResponse(data, arg, headers)
: this.#newResponse(data, arg) |
I think the proposal described in the following comments is a good compromise that does not involve major changes to the current code and is unlikely to cause a drop in performance. |
Sorry to bother you. Let's go as you suggested. Can you review it? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very refactoring 👍
Okay! Merging now. |
This PR reduces the bundle size using
#
for the private methods instead of theprivate
keyword when the code is minified.The result for the "Hello World" app with the
hono/tiny
preset. This is minified withesbuild --minify
command:479 bytes
will be reduced without changing any logic and without performance degradation!#
vsprivate
For example, you have the code:
If you use the
private
keyword for the private method, the function name is not minifed with esbuildInstead of
private
, you can use#
for the private method.Then, the function name will be minified!